package org.testis.utils.parametermodel;

import java.util.LinkedList;

/**
 * 
 * @author Cahit Emir Erel
 */
public class ParameterTable {

    private LinkedList<ParameterModel> m_parameterList = new LinkedList<ParameterModel>();
    private String[] m_columnNames = new String[2];
    private static final String[] DEFAULT_COLUMN_NAMES = { "Parameter", "Value" };

    /**
     * Creates an empty ParameterTable
     */
    public ParameterTable() {
	this(null, null, DEFAULT_COLUMN_NAMES);
    }

    /**
     * Creates a ParameterTable with the given parameters
     * 
     * @param list
     *            - Parameters to be added
     */
    public ParameterTable(ParameterModel[] list) {
	for (int i = 0; i < list.length; i++) {
	    m_parameterList.add(list[i]);
	}
    }

    /**
     * Creates a ParameterTable with the given parameters and column names
     * 
     * @param list
     *            - Parameters to be added
     * @param columns
     *            - Column names
     */
    public ParameterTable(ParameterModel[] list, String[] columns) {
	setColumnNames(columns);
	if (list != null) {
	    for (int i = 0; i < list.length; i++) {
		m_parameterList.add(list[i]);
	    }
	}
    }

    /**
     * Creates a ParameterTable with the given parameters and column names
     * 
     * @param inputParameters
     *            - Parameter names to be added
     * @param inputValues
     *            - Parameter values to be added
     * @param columns
     *            - Column names
     * @throws IndexOutOfBoundsException
     */
    public ParameterTable(String[] inputParameters, String[] inputValues,
	    String[] columns) {
	setColumnNames(columns);
	if (inputParameters != null && inputValues != null) {
	    for (int i = 0; i < inputParameters.length; i++) {
		m_parameterList.add(new ParameterModel(inputParameters[i],
			inputValues[i]));
	    }
	}
    }

    /**
     * Sets the column names of this ParameterTable
     * 
     * @param columns
     *            - Column names
     */
    public void setColumnNames(String[] columns) {
	if (columns != null && columns.length == 2) {
	    if (columns[0] == null) {
		m_columnNames[0] = DEFAULT_COLUMN_NAMES[0];
	    } else {
		m_columnNames[0] = columns[0];
	    }
	    if (columns[1] == null) {
		m_columnNames[1] = DEFAULT_COLUMN_NAMES[1];
	    } else {
		m_columnNames[1] = columns[1];
	    }
	} else {
	    m_columnNames[0] = DEFAULT_COLUMN_NAMES[0];
	    m_columnNames[1] = DEFAULT_COLUMN_NAMES[1];
	}
    }

    /**
     * Returns the number of rows in the table
     * 
     * @return number of rows in the table
     */
    public int getRowCount() {
	return m_parameterList.size();
    }

    /**
     * Returns the number of columns in the table NOTE: This method always
     * returns 2
     * 
     * @return number of columns in the table
     */
    public int getColumnCount() {
	return 2;
    }

    /**
     * Returns the name of the nth column
     * 
     * @param n
     *            - place of the column in the column list
     * @return name of the nth column
     * @throws IndexOutOfBoundsException
     */
    public String getColumnName(int n) {
	return m_columnNames[n];
    }

    /**
     * Returns the class of the nth column NOTE: This method always returns
     * String.class
     * 
     * @param n
     *            - place of the column in the column list
     * @return class of the nth column
     */
    public Class<?> getColumnClass(int n) {
	return String.class;
    }

    /**
     * Returns true if the cell at column n, row m is editable Column names in
     * row 0 are not editable
     * 
     * @param n
     *            - column number
     * @param m
     *            - row number
     * @return true if the cell at column n, row m is editable
     */
    public boolean isCellEditable(int n, int m) {
	if (m == 0) {
	    return false;
	} else {
	    return true;
	}
    }

    /**
     * Returns the value of the cell at column n, row m
     * 
     * @param m
     *            - row number
     * @param n
     *            - column number
     * @return value of the cell at column n, row m
     * @throws IndexOutOfBoundsException
     * @throws NullPointerException
     */
    public String getValueAt(int m, int n) {
	if (n == 0) {
	    return m_parameterList.get(m).getParameter();
	} else if (n == 1) {
	    return m_parameterList.get(m).getValue();
	}
	return null;
    }

    /**
     * Adds a new parameter to the table
     * 
     * @param parameter
     *            - name of the parameter to be added
     * @param value
     *            - value of the parameter to be added
     */
    public void addItem(String parameter, String value) {
	if (parameter != null && !parameter.equals("")) {
	    addItem(new ParameterModel(parameter, value));
	}
    }

    /**
     * Adds a new parameter to the table
     * 
     * @param parameter
     *            - parameter to be added
     */
    public void addItem(ParameterModel parameter) {
	m_parameterList.add(parameter);
    }

    /**
     * Removes parameter from the table
     * 
     * @param parameter
     *            - parameter to be removed
     */
    public void removeItem(ParameterModel parameter) {
	m_parameterList.remove(parameter);
    }

    /**
     * Removes the nth parameter from the table
     * 
     * @param n
     *            - place of the parameter to be removed
     * @throws IndexOutOfBoundsException
     */
    public void removeItem(int n) {
	m_parameterList.remove(n);
    }

    /**
     * Removes all parameters from the table
     */
    public void removeAllItems() {
	m_parameterList.clear();
    }

    /**
     * Returns the nth parameter in the table
     * 
     * @param n
     *            - place of the parameter
     * @return nth parameter in the table
     * @throws IndexOutOfBoundsException
     */
    public ParameterModel getItem(int n) {
	return m_parameterList.get(n);
    }

    /**
     * Returns all parameters in the table
     * 
     * @return all parameters in the table
     */
    public ParameterModel[] getAllItems() {
	return m_parameterList.toArray(new ParameterModel[m_parameterList
		.size()]);
    }

    /**
     * Set value of cell at row m, column n to the value of the given object
     * 
     * @param value
     *            - given object
     * @param m
     *            - row number
     * @param n
     *            - column number
     * @throws IndexOutOfBoundsException
     * @throws NullPointerException
     */
    public void setValueAt(Object value, int m, int n) {
	if (n == 0) {
	    m_parameterList.get(m).setParameter(value.toString());
	} else if (n == 1) {
	    m_parameterList.get(m).setValue(value.toString());
	}
    }
}
